<template>
  <div class="app-main">
    <div class="operation-contain">
      <div class="operation-left">
        <el-input v-model="list.filters.search" placeholder="请输入搜索内容" clearable prefix-icon="el-icon-search" size="medium" @input="getSearch"></el-input>
      </div>
      <div class="operation-right">
        <el-dropdown trigger="click" @command="handleCommand">
          <el-button v-perms="'info:resource:upload'" type="primary" size="medium" class="el-icon-upload pad" plain> 上传</el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item v-perms="'info:resource:upload'" :command="() => goUpload('file')">上传文件</el-dropdown-item>
            <el-dropdown-item v-perms="'info:resource:upload'" :command="() => goUpload('folder')">上传文件夹</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-button v-perms="'info:resource:move'" type="warning" size="medium" :disabled="multipleSelection.length > 0 ? false : true" @click.native="$refs.treeDialog.open(multipleSelection, 'move')">移动到</el-button>
        <el-button v-perms="'info:resource:copy'" type="success" size="medium" :disabled="multipleSelection.length > 0 ? false : true" @click.native="$refs.treeDialog.open(multipleSelection, 'copy')">复制到</el-button>
        <el-button v-perms="'info:resource:add'" type="primary" @click="$refs.addDialog.open()" size="medium" class="el-icon-circle-plus-outline"> 新增</el-button>
        <el-button v-perms="'info:resource:delete'" type="danger" @click="batchDelete" size="medium" class="el-icon-delete pad" :disabled="multipleSelection.length > 0 ? false : true"> 删除</el-button>
        <d-dropdown :isShow.sync="isShow" v-if="styleList === true"/>
      </div>
    </div>
    <div class="operation-bread">
      <el-breadcrumb separator=">">
        <template v-for="(item, index) in breadcrumb">
          <el-breadcrumb-item v-if="index < (breadcrumb.length - 1)" :key="index" :to="{ path: '/info/resource', query: { path: setQueryPath(index) } }">{{ item }}</el-breadcrumb-item>
          <el-breadcrumb-item v-else :key="index">{{ item }}</el-breadcrumb-item>
        </template>
        <el-breadcrumb-item v-if="breadcrumb.length === 1"></el-breadcrumb-item>
      </el-breadcrumb>
      <div class="exchange-icon" @click="styleList = !styleList">
        <i v-if="styleList === true" class="el-icon-menu" title="切换到缩略图模式"></i>
        <i v-else class="el-icon-s-operation" title="切换到列表模式"></i>
      </div>
    </div>
    <div v-if="styleList === true" class="table-contain">
      <el-table
        ref="table"
        :data="list.data"
        style="width: 100%;"
        row-key="id"
        border
        stripe
        v-loading="list.loading"
        @selection-change="handleSelectionChange"
        @row-click="rowClick">
        <el-table-column type="selection" width="55" label="选择" align="center">
        </el-table-column>
        <el-table-column v-if="isShow[0].value" label="资源名称" align="center" prop="name" min-width="120">
          <template v-slot="{ row }">
            <template v-if="row.isEdit === false">
              {{ row.name }}
            </template>
            <template v-else>
              <el-input type="text" ref="inputName" v-model="list.rename" @blur="rename(row, list.rename)" v-focus @keyup.enter.native="rename(row, list.rename)"></el-input>
            </template>
          </template>
        </el-table-column>
        <el-table-column v-if="isShow[1].value" label="类型" min-width="150" align="center" prop="type">
          <template v-slot="{ row }">
            <img class="cell-img" v-if="row.type === 'folder'" src="@/assets/icon/folder.png" alt="">
            <img class="cell-img" v-else-if="row.type === 'file'" :src="require(`@/assets/icon/${row.extension}.png`)" alt="">
          </template>
        </el-table-column>
        <el-table-column v-if="isShow[2].value" label="大小" min-width="120" align="center" prop="size">
          <template v-slot="{ row }">
            {{ row.size === 0 ? '-' : size(row.size) }}
          </template>
        </el-table-column>
        <el-table-column v-if="isShow[3].value" label="扩展名" min-width="120" align="center" prop="extension">
          <template v-slot="{ row }">
            {{ row.extension ? row.extension : '-' }}
          </template>
        </el-table-column>
        <el-table-column v-if="isShow[4].value" label="创建时间" align="center" prop="ctime" min-width="180">
          <template v-slot="{ row }">
            {{ row.ctime }}
          </template>
        </el-table-column>
        <el-table-column v-if="isShow[5].value" label="修改时间" align="center" prop="mtime" min-width="180">
          <template v-slot="{ row }">
            {{ row.mtime }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140" align="center" >
          <template v-slot="{ row }">
            <el-dropdown trigger="click" @command="handleCommand">
              <el-button type="primary" size="mini" class="pad">
                <i class="el-icon-more"></i>
              </el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item v-perms="'info:resource:update'" :command="() => update(row)">重命名</el-dropdown-item>
                <el-dropdown-item v-perms="'info:resource:copy'" :command="() => $refs.treeDialog.open([row.path], 'copy')">复制到</el-dropdown-item>
                <el-dropdown-item v-perms="'info:resource:move'" :command="() => $refs.treeDialog.open([row.path], 'move')">移动到</el-dropdown-item>
                <el-dropdown-item v-perms="'info:resource:download'" :command="() => download(row)">下载</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
            <el-button v-perms="'info:resource:delete'" slot="reference" type="danger" icon="el-icon-delete" size="mini" @click="confirmDelete(row)"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-else class="table-contain">
      <div class="list-contain" v-if="list.data.length > 0">
        <div class="list-item" 
          v-for="(item, index) in list.data"
          :key="index"
          @dblclick="rowClick(item)"
          @contextmenu.prevent="openMenu(item, $event, index)"
          :class="curIndex === index ? 'is-active' : ''">
          <img class="list-icon" v-if="item.type === 'folder'" src="@/assets/icon/folder.png" alt="">
            <img class="list-icon" v-else-if="item.type === 'file'" :src="require(`@/assets/icon/${item.extension}.png`)" alt="">
          <span>{{ item.name }}</span>
        </div>
      </div>
      <div class="list-contain" v-else>
        <div class="no-list">
          <i class="el-icon-folder-opened"></i>
          <span>暂无资源</span>
        </div>
      </div>
    </div>
    <my-dialog ref="myDialog" :dialogVisible.sync="dialogVisible" @getAll="getList" :list="list.data" />
    <add ref="addDialog" :dialogVisible.sync="addDialogVisible" @getAll="getList" :path="list.filters.path" />
    <d-right-menu
      ref="rightMenu"
      :isShowPopover.sync="isShowPopover"
      :popoverLeft="popoverLeft"
      :popoverTop="popoverTop"
      :popoverList="popoverList"
      @move="$refs.treeDialog.open([curItem.path], 'move')"
      @copy="$refs.treeDialog.open([curItem.path], 'copy')"
      @delete="confirmDelete(curItem)"
      @download="download(curItem)"
      :curItem="curItem"/>
    <tree ref="treeDialog" :dialogVisible.sync="treeDialogVisible" @getAll="getList" :curIndex.sync="curIndex" />
  </div>
</template>

<script>
import myDialog from './Dialog'
import add from './Add'
import tree from './Tree'
export default {
  name: 'InfoResource',
  components: {
    myDialog,
    add,
    tree
  },
  data () {
    return {
      isShow: [
        { label: '资源名称', value: true, disable: false },
        { label: '类型', value: true, disable: false },
        { label: '大小', value: true, disable: false },
        { label: '扩展名', value: true, disable: false },
        { label: '创建时间', value: true, disable: false },
        { label: '更新时间', value: true, disable: false },
      ],
      list: {
        data: [],
        loading: false,
        filters: {
          search: '',
          path: this.$route.query.path === undefined ? '/' : this.$route.query.path
        },
        rename: ''
      },
      dialogVisible: false,
      addDialogVisible: false,
      treeDialogVisible: false,
      treeType: 'move',
      multipleSelection: [],
      breadcrumb: [],
      styleList: true,
      curIndex: -1,
      curItem: null,
      isShowPopover: false, // 是否展示右键内容
      popoverLeft: 0, // 距离左边的距离
      popoverTop: 0, // 距离顶部的距离
      popoverList: [
        { name: '复制到', type: 'copy-document', val: 'copy' },
        { name: '移动到', type: 'aim', val: 'move' },
        { name: '下载', type: 'download', val: 'download' },
        { name: '删除', type: 'delete', val: 'delete' }
      ]
    }
  },
  directives: {
    focus: {
      inserted: el => {
        //因为el-input这是个组件，input外面被一层 div 包裹着
        //el打印出来是外面这个 div，需要找到内层的input
        el.querySelector('input').focus()
        el.querySelector('input').select() // 选中文字
      }
    }
  },
  created () {
    this.getList()
    if (this.$route.query.path === undefined || this.$route.query.path === '/') {
      this.breadcrumb = ['我的资源']
    } else {
      this.breadcrumb = [...['我的资源'], ...this.$route.query.path.split('/').slice(1)]
    }
  },
  watch: {
    $route (val) { // 监听路由参数变化
      if (val.query.path === undefined || val.query.path === '/') {
        this.list.filters.path = '/'
        this.breadcrumb = ['我的资源']
      } else {
        this.list.filters.path = val.query.path
        this.breadcrumb = [...['我的资源'], ...val.query.path.split('/').slice(1)]
      }
      this.getList()
    }
  },
  methods: {
    size(size) { // 将以字节为单位的文件大小格式化成以 byte kb mb gb 为单位的字符串
      size = parseInt(size)
      if (isNaN(size) || size === 0) {
        return '0'
      }
      if (size < 1024) {
        return '' + size + ' B'
      }
      size /= 1024
      if (size < 1024) {
        return '' + (Math.ceil(size * 100) / 100) + ' KB'
      }
      size /= 1024
      if (size < 1024) {
        return '' + (Math.ceil(size * 100) / 100) + ' MB'
      }
      size /= 1024
      if (size < 1024) {
        return '' + (Math.ceil(size * 100) / 100) + ' GB'
      }
      size /= 1024
      if (size < 1024) {
        return '' + (Math.ceil(size * 100) / 100) + ' TB'
      }
      return '' + (Math.ceil(size * 100 / 1024) / 100) + ' PB'
    },
    handleCommand (func) { // 下拉菜单事件
      func()
    },
    goUpload (type) {
      this.$router.push({ path: '/info/resource/upload', query: { type: type, path: this.$route.query.path ? this.$route.query.path : '/' } })
    },
    setQueryPath (index) { // 设置面包屑的query参数
      const tmp = JSON.parse(JSON.stringify(this.breadcrumb))
      if (index === 0) {
        return '/'
      } else {
        return '/' + tmp.slice(1).slice(0, index).join('/')
        // return tmp.slice(0, index + 1).join('/')
      }
    },
    update (row) { // 切换编辑框显示
      row.isEdit = true
      this.list.rename = row.name
    },
    rename (row, rename) { // 重命名
      if (row.name !== rename) {
        this.$API({
          name: 'UpdateResource',
          params: {
            path: row.path
          },
          headers: {
            'Content-Type': 'text/plain'
          },
          data: rename,
          requireAuth: true
        }).then (res => {
          if (res.data.code === 200) {
            this.getList()
          } else {
            this.$message.error(res.data.msg)
          }
        }).catch(error => {
          this.$message.error(error)
        }).finally(() => {
        })
      }
      row.isEdit = false
    },
    getSearch () {
      this.getList()
    },
    handleSelectionChange (val) { // 当选择项发生变化时会触发该事件
      const arr = []
      val.forEach(item => {
        arr.push(item.path)
      })
      this.multipleSelection = arr
    },
    getList () { // 获取列表
      this.list.loading = true
      this.$API({
        name: 'GetResourceList',
        params: {
          path: this.list.filters.path,
          search: this.list.filters.search
        },
        requireAuth: true
      }).then (res => {
        if (res.data.code === 200) {
          this.list.data = res.data.data
          this.list.data.forEach(item => {
            this.$set(item, 'isEdit', false)
          })
        } else {
          this.$message.error(res.data.msg)
        }
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.list.loading = false
      })
    },
    rowClick (row, column) { // 表格行被点击
      if ((this.styleList === true && row.type === 'folder' && column.label !=='操作' && column.label !=='选择' && row.isEdit === false) || this.styleList === false) {
        this.$router.push({ path: '/info/resource', query: { path: row.path } })
      }
      this.curIndex = null
    },
    confirmDelete (row) {
      this.$confirm('此操作将永久删除该资源, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.delete(row)
      }).catch(() => {
        this.curIndex = null
      })
    },
    delete (row) { // 删除
      this.$API({
        name: 'DeleteResource',
        params: {
          path: row.path
        },
        requireAuth: true
      }).then (res => {
        if (res.data.code === 200) {
          this.$message.success(res.data.msg)
        } else {
          this.$message.error(res.data.msg)
        }
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.getList()
        this.curIndex = null
      })
    },
    batchDelete () { // 批量删除

    },
    /**
     * 点击鼠标右键时，保存当前元素数据，并将当前元素的class设置高亮样式，其他元素为空
     */
    // 展开菜单
    openMenu (item, event, index) {
      this.curItem = item
      this.curIndex = index
      // 判断窗口大小
      const clientWidth = document.body.clientWidth
      const clientHeight = document.body.clientHeight
      // 鼠标右键边界值判断（100,178是右键菜单的宽高）
      if (event.clientX + 100 >= clientWidth) {
        this.popoverLeft = clientWidth - 100
      } else {
        this.popoverLeft = event.clientX
      }
      if (event.clientY + 178 >= clientHeight) {
        this.popoverTop = clientHeight - 178
      } else {
        this.popoverTop = event.clientY
      }
      this.isShowPopover = true // 显示自定义菜单栏
    },
    download (row) { // 下载
      this.$API({
        name: 'DownloadResource',
        params: {
          path: row.path,
          token: this.$Cookies.get('token')
        },
        headers: {
          'Content-Type': 'application/octet-stream'
        },
        requireAuth: true
      }).then (res => {
        window.open(`${res.config.url}?path=${res.config.params.path}&token=${res.config.params.token}`, '_self')
      }).catch(error => {
        this.$message.error(error)
      })
    }
  },
  // 解决 el-table 更新列时的抖动问题
  beforeUpdate() {
    this.$nextTick(() => {
      // 在数据加载完，重新渲染表格
      this.$refs.table && this.$refs.table.doLayout()
    }) 
  },
}
</script>

<style lang="scss" scoped>
.app-main ::v-deep .el-table__row {
  cursor: pointer;
}
.app-main {
  .cell-img {
    width: 30px;
    height: 30px;
  }
  .operation-bread {
    display: flex;
    justify-content: space-between;
    margin-bottom: 9px;
    align-items: center;
    .breadcrumb {
      padding: 0 10px 10px 0;
      font-size: 14px;
      cursor: pointer;
      span {
        &:hover {
          color:#409EFF;
        }
      }
    }
    .exchange-icon {
      cursor: pointer;
      &:hover {
        color: #409EFF;
      }
    }
  }
  .list-contain {
    display: flex;
    .no-list {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 30px;
      color: #a3a2a2;
      i {
        font-size: 60px;
        padding-bottom: 10px;
      }
    }
    .is-active {
      background-color: rgba(204, 239, 255, 0.2);
    }
    .list-item {
      padding: 20px;
      width: 140px;
      display: flex;
      flex-direction: column;
      align-items: center;
      cursor: pointer;
      font-size: 14px;
      flex-shrink: 0;
      .list-icon {
        width: 50px;
        height: 50px;
        margin-bottom: 10px;
      }
      &:hover {
        background-color: rgba(204, 239, 255, 0.2);
      }
    }
  }
}
</style>